#ifndef __Demo_Client_h__
#define __Demo_Client_h__

#define WIN32_LEAN_AND_MEAN
#include "windows.h"

#include <iostream>
#include <stdio.h>
#include <tchar.h>
#include <sstream>
#include <conio.h>

#include "ATMOS.h"
#include "ATMOS_LogManager.h"
#include "ATMOS_MSClient.h"
#include "ATMOS_MasterServerPacketID.h"

class DemoClient
{
	class GameClientListener : public ATMOS::PacketListener
	{
		friend class DemoClient;

	public:
		GameClientListener( DemoClient *demoClient  );
		virtual ~GameClientListener();

		virtual void onAtmosPacket( ATMOS::Packet *packet );
		virtual void onDisconnectionNotification( const std::string &senderGUID );
		virtual void onAlreadyConnected( const std::string &senderGUID );
		virtual void onIncompatibleProtocolVersion( const std::string &senderGUID );
		virtual void onRemoteDisconnectionNotification( const std::string &senderGUID );
		virtual void onRemoteConnectionLost( const std::string &senderGUID );
		virtual void onNewIncomingConnection( const std::string &senderGUID );
		virtual void onConnectionBanned( const std::string &senderGUID );
		virtual void onConnectionAttemptFailed( const std::string &senderGUID );
		virtual void onNoFreeIncomingConnections( const std::string &senderGUID );
		virtual void onInvalidPassword( const std::string &senderGUID );
		virtual void onConnectionLost( const std::string &senderGUID );
		virtual void onConnectionRequestAccepted( const std::string &senderGUID );
		virtual void onUnknownPacket( const std::string &senderGUID );
	
	private:
		DemoClient *mDemoClient;
	};

	class MSClientListener : public ATMOS::PacketListener
	{
		friend class DemoClient;		

	public:
		MSClientListener( DemoClient *demoClient, const std::string &name, int gamePort, 
			int gameServerPort );
		virtual ~MSClientListener();

		virtual void onAtmosPacket( ATMOS::Packet *packet );
		virtual void onDisconnectionNotification( const std::string &senderGUID );
		virtual void onAlreadyConnected( const std::string &senderGUID );
		virtual void onIncompatibleProtocolVersion( const std::string &senderGUID );
		virtual void onRemoteDisconnectionNotification( const std::string &senderGUID );
		virtual void onRemoteConnectionLost( const std::string &senderGUID );
		virtual void onNewIncomingConnection( const std::string &senderGUID );
		virtual void onConnectionBanned( const std::string &senderGUID );
		virtual void onConnectionAttemptFailed( const std::string &senderGUID );
		virtual void onNoFreeIncomingConnections( const std::string &senderGUID );
		virtual void onInvalidPassword( const std::string &senderGUID );
		virtual void onConnectionLost( const std::string &senderGUID );
		virtual void onConnectionRequestAccepted( const std::string &senderGUID );
		virtual void onUnknownPacket( const std::string &senderGUID );
	
	private:
		DemoClient *mDemoClient;
		std::string mName;
		int mPort, mGameServerPort;
	};

public:
	DemoClient( const std::string &name, int msPort, int gamePort, int gameServerPort );
	virtual ~DemoClient();

	void update();
		
	std::string getMSConnectionGUID() const;
	void listServers();

	void connectToGameServer();
	void disconnectFromGameServer();
	bool connectedToGameServer() const;

	std::string getGameLocalGUID() const;
	std::string getGameServerGUID() const;
	std::string getMSLocalGUID() const;
	std::string getMSServerGUID() const;
		
private:
	ATMOS::LogManager *mLogManager;
	ATMOS::MSClient *mMSClient;
	ATMOS::NetworkManagerClient mClient;
	bool mClientInitialized;
	bool mConnectedToGameServer;
	std::string mGameServerGUID;
	std::string mMSServerGUID;

	GameClientListener *mGameClientListener;
	MSClientListener *mMSClientListener;
};

#endif